package com.strato.rule.editor.v1_0_0;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.strato.annotation.osgi.v1_0_0.service.OsgiWired;
import com.strato.json.v1_0_0.exec.JSONUtils;
import com.strato.mvc.annotation.v1_0_0.annotation.method.RequestMapping;
import com.strato.mvc.annotation.v1_0_0.annotation.type.Controller;
import com.strato.mvc.api.v1_0_0.model.ModelAndView;
import com.strato.rule.core.v1_0_0.execution.Rule;
import com.strato.rule.core.v1_0_0.execution.RuleEngine;
import com.strato.rule.core.v1_0_0.execution.RuleItem;
import com.strato.rule.core.v1_0_0.execution.RuleSet;
import com.strato.rule.core.v1_0_0.storage.RuleSetStore;

@Controller
@com.strato.mvc.annotation.v1_0_0.annotation.type.RequestMapping("/re")
public class RuleEditorController {
	
	@OsgiWired
	private RuleSetStore ruleSetStore;
	
	@OsgiWired
	private RuleEngine ruleEngine;
	
	@RequestMapping("/loadRuleSet")
	public void loadRuleSet(HttpServletRequest request,HttpServletResponse response){
		String ruleSetId=request.getParameter("ruleSetId");
		RuleSet ruleSet = ruleSetStore.load(ruleSetId);
		try {
			PrintWriter out = response.getWriter();
			if(ruleSet==null){
				out.write("null");
			}else{
				out.write(ruleSet.toJson());
			}
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	@RequestMapping("/loadRuleTemplates")
	public void loadRuleTemplates(HttpServletRequest request,HttpServletResponse response){
		String ruleGroup=request.getParameter("ruleGroup");
		List<Rule> rules=ruleEngine.getByGroup(ruleGroup);
		List<Map<String,Object>> descriptions=new ArrayList<Map<String,Object>>();
		for(Rule rule:rules){
			descriptions.add(rule.describe());
		}
		try {
			String json = JSONUtils.getInstance().toJSON(descriptions);
			PrintWriter out = response.getWriter();
			out.write(json);
			out.flush();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
	}
	
	@RequestMapping("/loadLayout")
	public String loadLayout(HttpServletRequest request,ModelAndView mav){
		return "vm:views/layout@strato.rule.editor.v1_0_0";
	}
	
	@RequestMapping("/save")
	//Just for test
	public void saveorderrule(HttpServletRequest request,HttpServletResponse response){
		List<RuleSet> ruleSets = parseRuleSets(request);
		for(RuleSet ruleSet:ruleSets){
			String ruleSetId=ruleSet.getId();
			if(ruleSetId==null||"".equals(ruleSetId)){
				String uuid=UUID.randomUUID().toString();
				ruleSet.setId(uuid);
			}
			ruleSetStore.save(ruleSet);
		}
	}
	
	public static List<RuleSet> parseRuleSets(HttpServletRequest request){
		List<RuleSet> ruleSets=new ArrayList<RuleSet>();
		String[] ids = request.getParameterValues("ruleEditorId");
		if(ids!=null){
			for(String editorId:ids){
				String ruleSetId=request.getParameter(editorId+"ruleSetId");
				RuleSet ruleSet=new RuleSet();
				ruleSet.setId(ruleSetId);
				ruleSets.add(ruleSet);
				String[] ruleIds=request.getParameterValues(editorId+"ruleId");
				if(ruleIds!=null){
					List<RuleItem> ruleItems=new ArrayList<RuleItem>();
					for(String ruleId:ruleIds){
						RuleItem item=new RuleItem();
						ruleItems.add(item);
						item.setRuleId(ruleId);
						String[] paramIndexes = request.getParameterValues(editorId+"Param"+ruleId);
						Map<String, Object> params=null;
						for(String paramIndex:paramIndexes){
							String paramName=request.getParameter(editorId+"NameOf"+paramIndex);
							String paramValue=request.getParameter(editorId+"ValueOf"+paramIndex);
							if(params==null){
								params=new HashMap<String,Object>();
								item.setParams(params);
							}
							params.put(paramName, paramValue);
						}
					}
					ruleSet.setRuleItems(ruleItems);
				}
			}
		}
		return ruleSets;
	}
}
